package com.eight.cloud.message.producer;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.eight.cloud.core.global.exception.ParameterException;
import com.eight.cloud.core.global.model.BaseUser;
import com.eight.cloud.openfeign.message.model.SocketMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import java.util.HashMap;
import java.util.Map;

import static com.eight.cloud.core.global.constant.StrConstant.*;
import static com.eight.cloud.core.global.result.ResultCode.PARAM_TYPE_ERROR;
import static com.eight.cloud.openfeign.message.constant.SocketConstant.*;

/**
 * 推送消息
 *
 * @ClassName: PushMessage
 * @Author: TXC
 * @Date: 2024-10-11 10:51
 **/
@Component
@Slf4j
public class WebSocketPublisher {
    @Resource
    private SimpMessagingTemplate template;

    /**
     * 发送消息到指定topic
     * @param topic  主题
     * @param payload  消息体
     * @param contentType  消息类型
     */
    public void sendMessageToTopic(String topic, Object payload, String contentType) {
        Map<String, Object> headers = new HashMap<>();
        headers.put(CONTENT_TYPE, contentType);
        switch (contentType) {
            case APPLICATION_JSON:
                template.convertAndSend(topic, MessageBuilder.createMessage(payload, new MessageHeaders(headers)));
                break;
            case TEXT_PLAIN:
                template.convertAndSend(topic, payload, new MessageHeaders(headers));
                break;
            default:
                throw new ParameterException(PARAM_TYPE_ERROR);
        }
    }

    /**
     * 发送消息到指定用户
     * @param user  用户
     * @param destination  目的地
     * @param payload  消息体
     * @param contentType  消息类型
     */
    public void sendMessageToUser(String user, String destination, Object payload, String contentType) {
        Map<String, Object> headers = new HashMap<>();
        headers.put(CONTENT_TYPE, contentType);
        switch (contentType) {
            case APPLICATION_JSON:
                template.convertAndSendToUser(user, destination, MessageBuilder.createMessage(payload, new MessageHeaders(headers)));
                break;
            case TEXT_PLAIN:
                template.convertAndSendToUser(user, destination, payload, new MessageHeaders(headers));
                break;
            default:
                throw new ParameterException(PARAM_TYPE_ERROR);
        }
    }

    public void sendJsonMessageToTopic(String topic, Object payload) {
        sendMessageToTopic(topic, payload, APPLICATION_JSON);
    }

    public void sendTextMessageToTopic(String topic, Object payload) {
        sendMessageToTopic(topic, payload, TEXT_PLAIN);
    }

    public void sendJsonMessageToUser(String user, String destination, Object payload) {
        sendMessageToUser(user, destination, payload, APPLICATION_JSON);
    }

    public void sendTextMessageToUser(String user, String destination, Object payload) {
        sendMessageToUser(user, destination, payload, TEXT_PLAIN);
    }

    public void sendTextMessage(SocketMessage<?> socketMessage) {
        if (ObjectUtil.isNotNull(socketMessage)) {
            if (StrUtil.isNotEmpty(socketMessage.getDestination())) {
                log.info("推送Text websocket消息");
                if (ObjectUtil.isNull(socketMessage.getTo())) {
                    sendTextMessageToTopic(SOCKET_TOPIC + socketMessage.getDestination(), socketMessage.getPayload());
                } else if (ObjectUtil.isNotNull(socketMessage.getTo())) {
                    sendTextMessageToUser(analysisUserSign(socketMessage.getTo()), SOCKET_MASSAGE + socketMessage.getDestination(), socketMessage.getPayload());
                }
                log.info("----------Text 消息发送完毕----------");
            }
        }
    }

    public void sendJsonMessage(SocketMessage<?> socketMessage) {
        if (ObjectUtil.isNotNull(socketMessage)) {
            if (StrUtil.isNotEmpty(socketMessage.getDestination())) {
                log.info("推送Json websocket消息");
                if (ObjectUtil.isNull(socketMessage.getTo())) {
                    sendJsonMessageToTopic(SOCKET_TOPIC + socketMessage.getDestination(), socketMessage.getPayload());
                } else if (ObjectUtil.isNotNull(socketMessage.getTo())) {
                    sendJsonMessageToUser(analysisUserSign(socketMessage.getTo()), SOCKET_MASSAGE + socketMessage.getDestination(), socketMessage.getPayload());
                }
                log.info("----------Json 消息发送完毕----------");
            }
        }
    }

    public void send(SocketMessage<?> socketMessage) {
        if (ObjectUtil.isNotNull(socketMessage)) {
            switch (socketMessage.getContentType()) {
                case APPLICATION_JSON:
                    sendJsonMessage(socketMessage);
                    break;
                case TEXT_PLAIN:
                    sendTextMessage(socketMessage);
                    break;
                default:
                    throw new ParameterException(PARAM_TYPE_ERROR);
            }
        }
    }

    private String analysisUserSign(BaseUser baseUser) {
        return baseUser.getUserType().name() + DASH + baseUser.getUuid();
    }
}
